iT邦幫忙

2024 iThome 鐵人賽

DAY 5
1
DevOps

DevOps需要的技能樹...(應該)都點得到!系列 第 5

Day 5: Kubernetes 基本架構及安裝

  • 分享至 

  • xImage
  •  

本章節「Kubernetes (k8s)」概要

Day 5: Kubernetes 基本架構及安裝
Day 6: 使用 kubectl 指令管理 Kubernetes 集群
Day 7: Kubernetes Pod 與 Deployment 深入解析
Day 8: Kubernetes Service 與負載均衡機制
Day 9: Kubernetes Persistent Volumes (PV) 與 Persistent Volume Claims (PVC)

認識Kubernetes

Kubernetes 是一個開源的容器編排平台,旨在自動化應用程序的部署、擴展和管理。它最早由 Google 開發,後來捐贈給了 CNCF(Cloud Native Computing Foundation),現已成為容器化應用程序管理的業界標準。

Kubernetes 的基本架構由多個核心組件組成,每個組件都在系統中扮演著關鍵角色。

Master 節點
Master 節點是 Kubernetes 的控制平面,負責管理整個集群的狀態。它由以下幾個核心組件組成:

API Server:
Kubernetes 的前端,所有的操作請求都通過 API Server 來處理。它提供了 RESTful API,允許用戶、系統組件以及外部應用進行交互。

etcd:
分佈式鍵值存儲系統,用來保存整個集群的配置數據和狀態信息。所有的集群數據都存儲在 etcd 中,並且它保證數據的一致性。

Controller Manager:
負責管理集群中的各種控制器,這些控制器監控集群狀態並執行相應的操作來達到預期的狀態。例如,ReplicaSet Controller 確保某個應用有指定數量的 Pod 正在運行。

Scheduler:
負責將新創建的 Pod 安排到合適的工作節點(Node)上。Scheduler 根據資源使用情況、策略和約束條件來做出決策,將 Pod 分配給能夠滿足需求的節點。

Node 節點
Node 節點是 Kubernetes 集群中的工作節點,負責運行應用程序的 Pod。每個 Node 上都運行著以下組件:

Kubelet:
Node 上的主要代理程序,它負責監控 Pod 狀態並報告給 API Server,同時還會根據需要啟動和停止容器。

Container Runtime:
負責在 Node 上運行容器的軟體。常見的容器運行時包括 Docker、containerd 和 CRI-O。

Kube Proxy:
處理 Pod 網絡的負載均衡和網絡代理,確保集群中各個 Pod 之間以及 Pod 與外部之間的網絡通信。

Pod 和 Service
Pod:
Kubernetes 中最小的部署單位,一個 Pod 可以包含一個或多個容器,這些容器共享同一個網絡命名空間和存儲卷。

Service:
用於定義一組 Pod 的永久訪問策略,即使這些 Pod 隨時可能被創建或刪除。Service 提供一個穩定的網絡端點來訪問這些 Pod。

https://ithelp.ithome.com.tw/upload/images/20240803/201683843f5e4sYS0o.jpg

這些不用在當下馬上理解,等以後debug的時候就會理解了:)

前置作業

  • 配置k8s網路
cat << EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
cat << EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables  = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward                 = 1
EOF
sudo modprobe overlay
sudo modprobe br_netfilter
sudo sysctl --system
  • 關閉swap(k8s不允許swap)
sudo nano /etc/fstab

貼入以下內容

#將swap註解掉(如下)
# /swap.img     none    swap    sw      0       0

並手動執行關閉

sudo swapoff -a
  • (擇一)方案一:安裝containerd
    若有多個節點(node)則每個節點都需要安裝
sudo apt install -y containerd
sudo mkdir -p /etc/containerd
sudo containerd config default|sudo tee /etc/containerd/config.toml
sudo systemctl restart containerd
sudo apt-get install -y bridge-utils
sudo modprobe br_netfilter
echo "net.ipv4.ip_forward = 1"|sudo tee -a /etc/sysctl.conf
sudo sysctl -p

-(擇一)方案二:安裝cri-dockerd(範例是用這個)

#下載go和cri-dockerd
git clone https://github.com/Mirantis/cri-dockerd.git
cd cri-dockerd/
wget https://go.dev/dl/go1.21.3.linux-amd64.tar.gz
sudo tar -C /usr/local -xzf go1.21.3.linux-amd64.tar.gz

#指向環境變數
mkdir ~/.go
GOROOT=/usr/local/go
GOPATH=~/.go
PATH=$PATH:$GOROOT/bin:$GOPATH/bin

#檢查
go version

#編譯並安裝cri-dockerd
sudo apt install make
make cri-dockerd

#指向環境變數
mkdir -p /usr/local/bin

sudo install -o root -g root -m 0755 cri-dockerd /usr/local/bin/cri-dockerd
sudo install packaging/systemd/* /etc/systemd/system
sudo sed -i -e 's,/usr/bin/cri-dockerd,/usr/local/bin/cri-dockerd,' /etc/systemd/system/cri-docker.service

#重啟
sudo systemctl daemon-reload
sudo systemctl enable --now cri-docker.socket

#檢查是否active
systemctl status cri-docker.service
  • 安裝docker engine(若上一章已完成則可不做)
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
  • 配置權限(若上一章已完成則可不做)
sudo groupadd docker
sudo gpasswd -a $USER docker
sudo usermod -aG docker $USER
newgrp docker 

安裝k8s

  • 安裝k8s三件套(kubeadm, kubelet, kubectl)
    若有多個節點(node)則每個節點都需要安裝
#(擇一)方案一:直接安裝最新版
sudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates curl
curl -fsSL https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
sudo apt-add-repository "deb http://apt.kubernetes.io/ kubernetes-xenial main"
sudo apt-get update
sudo apt-get install -y kubectl kubelet kubeadm
#(擇一)方案二:安裝指定版本
sudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates curl
curl -fsSL https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
sudo apt-add-repository "deb http://apt.kubernetes.io/ kubernetes-xenial main"
sudo apt-get update
sudo apt install -y kubectl=1.26.3-00 kubelet=1.26.3-00 kubeadm=1.26.3-00
#(擇一)方案三:若上述操作提示PUBKEY失效
sudo mkdir -p /etc/apt/keyrings
echo "deb [signed-by=/etc/apt/keyrings/kubernetes.gpg] https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list
curl -fsSL https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes.gpg
sudo apt-add-repository "deb http://apt.kubernetes.io/ kubernetes-xenial main"
sudo apt-get update
sudo apt install -y kubectl=1.23.17-00 kubelet=1.23.17-00 kubeadm=1.23.17-00
  • 新增開機腳本
sudo nano /etc/rc.local

貼入以下內容

#!/bin/sh -e
swapoff -a
export KUBECONFIG=$HOME/.kube/config
exit 0

加入執行權限

sudo chmod u+x /etc/rc.local
  • 鎖定k8s版本
sudo apt-mark hold kubelet kubeadm kubectl
  • 查看相依套件及版本(只有master節點做)
kubeadm config images list
  • 安裝相依套件(只有master節點做)
sudo kubeadm config images pull
  • (擇一)containerd版本的初始化集群(只有master節點做)
    只需修改master ip,不需要修改pod內網網段(除非必要)
sudo kubeadm init --apiserver-advertise-address=<master ip> --pod-network-cidr=10.244.0.0/16 --ignore-preflight-errors=Swap --cri-socket unix:///run/containerd/containerd.sock

-(擇一)cri-dockerd版本的初始化集群(只有master節點做)(範例是用這個)
只需修改master ip,不需要修改pod內網網段(除非必要)

sudo kubeadm init --kubernetes-version=v1.26.3 --apiserver-advertise-address=<master ip> --pod-network-cidr=10.244.0.0/16 --ignore-preflight-errors=Swap --cri-socket unix:///var/run/cri-dockerd.sock

初始化完成之後螢幕上會打印join指令
到其他節點(node)上執行加入集群的指令

sudo kubeadm join <master ip>:6443 --token <剛才螢幕上給你的token> \
	--discovery-token-ca-cert-hash sha256:<剛才螢幕上給你的cert> --cri-socket unix:///var/run/cri-dockerd.sock
  • 配置環境變數(master節點做)
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
  • 配置權限(master節點做)
sudo chown $(id -u):$(id -g) $HOME/.kube/config
  • 在其他節點(node)事先建立存放目錄(node節點做)
mkdir -p $HOME/.kube
  • 將conf文件傳送給其他節點(master節點做)
sudo scp /etc/kubernetes/admin.conf <user>@<節點ip>:~/.kube/config
  • 也配置權限(拿到conf之後node節點做)
sudo chown $(id -u):$(id -g) $HOME/.kube/config
  • 安裝集群網路插件(只在master節點做)
kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml
  • 查看節點是否正常
kubectl get nodes

https://ithelp.ithome.com.tw/upload/images/20240803/20168384IH1kkEocZp.jpg

同場加映:排錯思路

  • 節點無法加入集群
    請檢查conf文件是否有確實傳給node節點並且賦予權限

  • 節點not ready
    1.請檢查網路套件是否正常啟用

kubecte get pod --all-namespaces

2.請檢查初始化集群的init指令是否完整有帶上所有參數

  • 有個步驟做錯了,如何重來?
#方案一:全部殺光(不建議)
sudo kubeadm reset --cri-socket  unix:///var/run/cri-dockerd.sock
sudo apt-get purge kubeadm kubectl kubelet kubernetes-cni kube*
sudo apt-get autoremove
sudo rm -rf ~/.kube
#方案二:重新初始化集群(推薦)
#重置
sudo kubeadm reset --cri-socket unix:///var/run/cri-dockerd.sock
#刪除config
sudo rm $HOME/.kube/config
重建
sudo kubeadm init ... 參考上面步驟繼續往下做

小觀念:
集群間相認的是init時來自master節點產生的$HOME/.kube/config這個文件

參考來源:

Kubernetes官方網站


上一篇
Day 4: 如何使用 Docker Compose 管理多容器應用程式
下一篇
Day 6: 使用 kubectl 指令管理 Kubernetes 集群
系列文
DevOps需要的技能樹...(應該)都點得到!25
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言